package com.shinhye.elephantsafe;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import net.tsz.afinal.FinalHttp;
import net.tsz.afinal.http.AjaxCallBack;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.animation.AlphaAnimation;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.shinhye.elephantsafe.service.AutoKillService;
import com.shinhye.elephantsafe.service.ShowAddressService;
import com.shinhye.elephantsafe.service.TelephonySafeService;
import com.shinhye.elephantsafe.service.WatchDogService;
import com.shinhye.elephantsafe.utils.ShortcutUtils;
import com.shinhye.elephantsafe.utils.StreamTools;

public class SplashActivity extends Activity {
	private final String TAG = "SplashActivity";
	private final int ENTER_HOME = 0;
	private final int UPDATE_DIALOG = 1;
	private final int URL_EXCEPTION = 2;
	private final int IO_EXCEPTION = 3;
	private final int JSON_EXCEPTION = 4;
	private final int TIME_OUT = 5;
	private String description;
	private String apkurl;
	private SharedPreferences sp;
	
	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch(msg.what) {
			case ENTER_HOME:
				toHomeActivity();
				break;
			case UPDATE_DIALOG:
				Log.i(TAG, "显示更新的对话框");
				updateDialog();
				break;
			case URL_EXCEPTION:
				Toast.makeText(SplashActivity.this, "URL解析出错啦~~", Toast.LENGTH_SHORT).show();
				toHomeActivity();
				break;
			case IO_EXCEPTION:
				Toast.makeText(SplashActivity.this, "网络异常~~", Toast.LENGTH_SHORT).show();
				toHomeActivity();
				break;
			case JSON_EXCEPTION:
				Toast.makeText(SplashActivity.this, "更新文件出错啦~~", Toast.LENGTH_SHORT).show();
				toHomeActivity();
				break;
			case TIME_OUT:
				Toast.makeText(SplashActivity.this, "出错啦！无法连接到站点~~", Toast.LENGTH_SHORT).show();
				toHomeActivity();
				break;
			}
		};
	};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        
        TextView tv_version = (TextView) findViewById(R.id.tv_version);
    	tv_version.append(getVersion());
    	
    	SharedPreferences sp = getSharedPreferences("Setting", MODE_PRIVATE);
    	ShortcutUtils.create(this, false);
    	
    	if(sp.getBoolean("autoupdate", true)) {
    		checkUpdate();
    	} else {
    		handler.postDelayed(new Runnable() {
				@Override
				public void run() {
					toHomeActivity();
				}
    		}, 2000);
    	}
    	
    	AlphaAnimation aa = new AlphaAnimation(0.2f, 1.0f);
    	aa.setDuration(700);
    	findViewById(R.id.rl_splash).setAnimation(aa);
    	
    	init();
    }
    
    /**
     * Initialization function.
     */
    private void init() {
    	sp = getSharedPreferences("Setting", MODE_PRIVATE);
    	
    	copyDbToRes("address.db");
    	copyDbToRes("commonnum.db");
    	copyDbToRes("antivirus.db");
    	
    	openAddressService();
    	openTelephonyService();
    	openAutoKillService();
    	openWatchDogService();
    }
    
    /**
     * Refer to SharedPreference to decide if it need to open WatchDogService.
     */
    private void openWatchDogService() {
    	boolean watchdog = sp.getBoolean("watchdog", false);
    	Intent service = new Intent(this, WatchDogService.class);
    	if(watchdog) {
    		startService(service);
    	}
	}

	/**
     * Refer to SharedPreference to decide if it need to open AutoKillService.
     */
    private void openAutoKillService() {
    	boolean autokill = sp.getBoolean("autokill", false);
    	Intent service = new Intent(this, AutoKillService.class);
    	if(autokill) {
    		startService(service);
    	}
	}

	/**
     * Refer to SharedPreference to decide if it need to open ShowAddressService.
     */
    private void openAddressService() {
    	boolean showaddress = sp.getBoolean("showaddress", true);
    	Intent service = new Intent(this, ShowAddressService.class);
    	if(showaddress) {
    		startService(service);
    	}
    }
    
    /**
     * Refer to SharedPreference to decide if it need to open openTelephonyService.
     */
    private void openTelephonyService() {
    	boolean intercept = sp.getBoolean("intercept", true);
    	Intent service = new Intent(this, TelephonySafeService.class);
    	if(intercept) {
    		startService(service);
    	}
    }
    
    /**
     * Show the dialog to choose if update or not.
     */
    private void updateDialog() {
    	AlertDialog.Builder builder = new Builder(this);
    	builder.setTitle("发现新版本");
    	builder.setIcon(android.R.drawable.ic_dialog_info);
    	
    	//1. 用户无法按返回键取消，用户体验不好
//    	builder.setCancelable(false);
    	//2. 用户可以取消。
    	builder.setOnCancelListener(new OnCancelListener() {
			@Override
			public void onCancel(DialogInterface dialog) {
				toHomeActivity();
			}
		});
    	
    	builder.setMessage(description);
    	builder.setPositiveButton("确定升级", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
					FinalHttp finalHttp = new FinalHttp();
					finalHttp.download(apkurl, Environment.getExternalStorageDirectory().getAbsolutePath() + "/update.apk", new AjaxCallBack<File>() {
						
						private ProgressBar progressBar;

						@Override
						public void onFailure(Throwable t, int errorNo,
								String strMsg) {
							super.onFailure(t, errorNo, strMsg);
							t.printStackTrace();
							Toast.makeText(SplashActivity.this, "更新失败！", Toast.LENGTH_SHORT).show();
							toHomeActivity();
						}
						
						@Override
						public void onSuccess(File t) {
							super.onSuccess(t);
							Toast.makeText(SplashActivity.this, "下载完成，即将启动安装程序...", Toast.LENGTH_SHORT).show();
							installAPK(t);
						}
						
						private void installAPK(File t) {
							toHomeActivity();
							Intent intent = new Intent();
							intent.setAction("android.intent.action.VIEW");
							intent.setDataAndType(Uri.fromFile(t), "application/vnd.android.package-archive");
							startActivity(intent);
							t.deleteOnExit();
						}

						@Override
						public void onLoading(long count, long current) {
							super.onLoading(count, current);
							progressBar.setProgress((int) (current * 100 / count));
						}
						
						@Override
						public void onStart() {
							super.onStart();
							progressBar = (ProgressBar) findViewById(R.id.progressBar1);
							progressBar.setVisibility(ProgressBar.VISIBLE);
						}
					});
				} else {
					Toast.makeText(SplashActivity.this, "SD卡不存在，无法更新！", Toast.LENGTH_SHORT).show();
					toHomeActivity();
				}
				
			}
		});
    	builder.setNegativeButton("下次再说", new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				toHomeActivity();
			}
		});
    	
    	builder.show();
	}

	/**
     * Go to the Home Activity.
     */
    private void toHomeActivity() {
		Intent intent = new Intent();
		intent.setClass(this, HomeActivity.class);
		startActivity(intent);
		finish();
		
	}

	/**
     * Check for update.
     */
    private void checkUpdate() {
    	new Thread(){

			public void run() {
    			Message msg = Message.obtain();
    			long start_time = System.currentTimeMillis();
    			try {
					URL url = new URL(getString(R.string.UpdateInfoUrl));
					HttpURLConnection conn = (HttpURLConnection) url.openConnection();
					conn.setConnectTimeout(4000);
					conn.setReadTimeout(4000);
					conn.setRequestMethod("GET");
					if(conn.getResponseCode() == 200) {
						String result = StreamTools.getStringFromStream(conn.getInputStream());
						Log.i(TAG, result);
						JSONObject json = new JSONObject(result);
						String version = json.getString("version");
						description = json.getString("description");
						apkurl = json.getString("apkurl");
						
						if(getVersion().equals(version)) {
							msg.what = ENTER_HOME;
						} else {
							msg.what = UPDATE_DIALOG;
						}
					} else {
						msg.what = TIME_OUT;
					}
				} catch (MalformedURLException e) {
					msg.what = URL_EXCEPTION;
					e.printStackTrace();
//				} catch (SocketTimeoutException e) {
//					msg.what = TIME_OUT;
//					e.printStackTrace();
				} catch (IOException e) {
					msg.what = IO_EXCEPTION;
					e.printStackTrace();
				} catch (JSONException e) {
					msg.what = JSON_EXCEPTION;
					e.printStackTrace();
				} finally {
	    			long end_time = System.currentTimeMillis();
	    			long delay_time = end_time - start_time;
	    			//等2秒钟
	    			if(delay_time < 2000) {
	    				try {
							Thread.sleep(2000 - delay_time);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
	    			}
	    			
	    			handler.sendMessage(msg);
				}
    		};
    	}.start();
    }

    /**
     * Get the version name of this application.
     * @return VersionName
     */
    private String getVersion() {
    	PackageManager packageManager = getPackageManager();
    	try {
			PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0);
			return packageInfo.versionName;
		} catch (NameNotFoundException e) {
			e.printStackTrace();
			return "";
		}
    }
    
    /**
     * Copy DB file from asssets directory to res directory.
     */
    private void copyDbToRes(String dbName) {
    	FileOutputStream fos = null;
    	InputStream is = null;
    	File file = new File(getFilesDir(), dbName);
    	if(file.exists())
    		return;
    	try {
    		fos = new FileOutputStream(file);
    		is = getAssets().open(dbName);
			byte[] bs = new byte[1024];
			int len;
			while((len = is.read(bs)) != -1) {
				fos.write(bs, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fos.close();
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
    }
    
}
